package com.syh.jn.scm.infrastructure.repository.impl.supplier.stock;

import cn.redscarf.commons.util.other.ExtStringUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AggregateRepoMybatisImplTmpl;
import com.syh.jn.scm.domain.supplier.entity.stock.StockOtherOutBill;
import com.syh.jn.scm.domain.supplier.entity.stock.StockOtherOutBillItem;
import com.syh.jn.scm.domain.supplier.repository.stock.StockOtherOutBillReadRepository;
import com.syh.jn.scm.dto.supplier.stock.StockOtherOutBillItemVo;
import com.syh.jn.scm.dto.supplier.stock.StockOtherOutBillVo;
import com.syh.jn.scm.infrastructure.repository.model.base.StorehouseModel;
import com.syh.jn.scm.infrastructure.repository.model.stock.stockOtherOutBill.StockOtherOutBillItemModel;
import com.syh.jn.scm.infrastructure.repository.model.stock.stockOtherOutBill.StockOtherOutBillModel;
import com.syh.jn.scm.infrastructure.repository.utils.MybatisTemplate;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import com.syh.jn.scm.infrastructure.wrapper.BaseResolve;
import com.syh.jn.scm.infrastructure.wrapper.ResolveToSQL;
import lombok.extern.java.Log;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 其他出入库
 */
@Log
@Repository("stockOtherOutReadRepositoryMbImpl")
public class StockOtherOutBillReadRepositoryMbImpl implements StockOtherOutBillReadRepository {

  private AggregateRepoMybatisImplTmpl<StockOtherOutBillVo, StockOtherOutBillModel, Long> billTmpl =
          new AggregateRepoMybatisImplTmpl.Builder()
                  .listTypeClass(StockOtherOutBillVo.class)
                  .modelClass(StockOtherOutBillModel.class).build();
  private AggregateRepoMybatisImplTmpl<StockOtherOutBillItemVo, StockOtherOutBillItemModel, Long> itemTmpl =
          new AggregateRepoMybatisImplTmpl.Builder()
                  .listTypeClass(StockOtherOutBillItemVo.class)
                  .modelClass(StockOtherOutBillItemModel.class).build();


  @Override
  public StockOtherOutBillVo getById(Long aLong) {
    return billTmpl.getById(aLong);
  }

  @Override
  public StockOtherOutBill getById(Long id, boolean haveItems) {
    log.warning("该接口暂不实现");
    return null;
  }

  @Override
  public StockOtherOutBillItem getItemByItemId(Long id) {
    log.warning("该接口暂不实现");
    return null;
  }

  @Override
  public StockOtherOutBillVo getOne(Wrapper wrapper) {
    return billTmpl.getOne(wrapper);
  }

  @Override
  public boolean contains(Long aLong) {
    return this.billTmpl.contains(aLong);
  }

  @Override
  public List<StockOtherOutBillVo> getList(Wrapper wrapper) {
    return this.billTmpl.getList(wrapper);
  }

  @Override
  public List<StockOtherOutBillVo> findListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return this.billTmpl.findListPage(wrapper, startRow, count);
  }

  @Override
  public int getCount(Wrapper wrapper) {
    StringBuffer sqlSb = new StringBuffer();
    String viewSql = this.billTmpl.getQuerySql().toString();
    String viewSqlAry[] = viewSql.split("\\s*FROM\\s*");
    sqlSb.append("SELECT COUNT(DISTINCT stockOtherOut.ID) AS COUNT FROM ");
    for (int i = 1; i <= viewSqlAry.length - 1; i++) {
      if (i > 1) {
        sqlSb.append(" FROM ").append(viewSqlAry[i]);
      } else {
        sqlSb.append(viewSqlAry[i]);
      }
    }
    BaseResolve resolveToSQL = new ResolveToSQL(wrapper, this.billTmpl.getWrapperParseMethods());
    sqlSb.append(" WHERE 1=1 ");
    sqlSb.append(resolveToSQL.resolve());

    Map resultM = MybatisTemplate.selectOne(sqlSb.toString());
    return Integer.parseInt(resultM.get("COUNT").toString());
  }

  @Override
  public List<StockOtherOutBillItemVo> findStockOtherOutBillItemVoByBillId(Long stockOtherOutBillId) {
    Wrapper wrapper = Wrapper.build().append(Restrictions.eq("stockOtherOutBillId", stockOtherOutBillId));
    return this.itemTmpl.getList(wrapper);
  }

  @Override
  public List<StockOtherOutBillItemVo> findStockOtherOutBillItemVoListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return this.itemTmpl.findListPage(wrapper, startRow, count);
  }

  @Override
  public int findStockOtherOutBillItemVoCount(Wrapper wrapper) {
    return this.itemTmpl.getCount(wrapper);
  }

  public StockOtherOutBillReadRepositoryMbImpl() {
    // 初始化查询语句 stockOtherOutBillSql
    SQL stockOtherOutBillSql = new SQL() {{
      SELECT(
              "DISTINCT stockOtherOut.ID",
              SQLAliasGenerateUtil.aliasGenerate(StockOtherOutBillModel.class, "stockOtherOut", null),
              "storehouse.NAME AS storehouseName",
              "account.NAME AS operatorName"
      );
      FROM("T_STOCK_OTHER_OUT_BILL stockOtherOut");
      LEFT_OUTER_JOIN(
              "T_BASE_STOREHOUSE storehouse on stockOtherOut.STOREHOUSE_ID = storehouse.ID"
      );
      LEFT_OUTER_JOIN(
              "T_SYSTEM_ACCOUNT account on stockOtherOut.OPERATOR_ID = account.ID"
      );
      LEFT_OUTER_JOIN(
              "T_STOCK_OTHER_OUT_BILL_ITEM item on item.STOCK_OTHER_OUT_BILL_ID = stockOtherOut.ID"
      );
    }};
    this.billTmpl.setQuerySql(stockOtherOutBillSql);
    //初始化查询条件解析 stockOtherOutBillMap
    final HashMap<String, String> stockOtherOutBillMap = new HashMap<>();
    stockOtherOutBillMap.put("id", "stockOtherOut.ID");
    stockOtherOutBillMap.put("code", "stockOtherOut.CODE");
    stockOtherOutBillMap.put("status", "stockOtherOut.STATUS");
    stockOtherOutBillMap.put("inputDateTimestamp", "stockOtherOut.INPUT_DATE_TIMESTAMP");
    stockOtherOutBillMap.put("storehouseId", "stockOtherOut.STOREHOUSE_ID");
    stockOtherOutBillMap.put("businessEntityId", "stockOtherOut.BUSINESS_ENTITY_ID");
    stockOtherOutBillMap.put("goodsId", "item.GOODS_ID");
    stockOtherOutBillMap.put("goodsName", "item.GOODS_NAME");
    this.billTmpl.setWrapperParseMethods((propertyName) -> {
      return stockOtherOutBillMap.get(propertyName);
    });

    // stockOtherOutBillItem
    String stockOtherOutBillTable = this.billTmpl.getModelTableName(StockOtherOutBillModel.class);
    String stockOtherOutBillItemTable = this.billTmpl.getModelTableName(StockOtherOutBillItemModel.class);
    String storehouseTable = this.billTmpl.getModelTableName(StorehouseModel.class);
    SQL stockOtherOutBillItemSql = new SQL() {{
      SELECT(
              SQLAliasGenerateUtil.aliasGenerate(StockOtherOutBillItemModel.class, "stockOtherOutItem", null),
              "storehouse.NAME as storehouseName"
      );
      FROM(
              ExtStringUtils.buildString(stockOtherOutBillItemTable, " stockOtherOutItem")
      );
      INNER_JOIN(
              ExtStringUtils.buildString(stockOtherOutBillTable, " stockOtherOut on stockOtherOutItem.STOCK_OTHER_OUT_BILL_ID = stockOtherOut.ID")
      );
      LEFT_OUTER_JOIN(
              ExtStringUtils.buildString(storehouseTable + " storehouse on stockOtherOut.STOREHOUSE_ID = storehouse.ID")
      );
    }};
    this.itemTmpl.setQuerySql(stockOtherOutBillItemSql);
    //初始化查询条件解析 stockOutItem
    final HashMap<String, String> stockOtherOutBillItemMap = new HashMap<>();
    stockOtherOutBillItemMap.put("id", "stockOtherOutItem.ID");
    stockOtherOutBillItemMap.put("otherOutBillId", "stockOtherOutItem.STOCK_OTHER_OUT_BILL_ID");
    stockOtherOutBillItemMap.put("status", "stockOtherOut.STATUS");
    stockOtherOutBillItemMap.put("inputDateTimestamp", "stockOtherOut.INPUT_DATE_TIMESTAMP");
    stockOtherOutBillItemMap.put("storehouseId", "stockOtherOut.STOREHOUSE_ID");
    stockOtherOutBillItemMap.put("businessEntityId", "stockOtherOut.BUSINESS_ENTITY_ID");
    this.itemTmpl.setWrapperParseMethods((propertyName) -> {
      return stockOtherOutBillItemMap.get(propertyName);
    });


  }
}
